using Agron.Security.ClientLayer;
using Agron.Data.Contracts;
using Agron.Services.Proxies;

using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;

using System;
using System.ComponentModel;
using System.Drawing;
using System.ServiceModel;
using System.Windows.Forms;


namespace Agron.UI.SmartClient
{
    partial class StartSessionForm : DialogBase
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="StartSessionForm"/> class.
        /// </summary>
        public StartSessionForm()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Handles the DoWork event of the loadBackgroundWorker control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.DoWorkEventArgs"/> instance containing the event data.</param>
        protected override void OnLoadBackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
        {
            base.OnLoadBackgroundWorkerDoWork(sender, e);

            DateTime max = DateTime.Now.AddHours(2d);
            DateTime min = DateTime.Now.Subtract(new TimeSpan(2, 0, 0));

            using (SchedulerServiceProxy sessionManager = new SchedulerServiceProxy())
            {
                e.Result = sessionManager.GetRange(AgronPrincipal.Current.AgronIdentity.Profile.UserId, min, max);
            }
        }

        /// <summary>
        /// Handles the RunWorkerCompleted event of the loadBackgroundWorker control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.RunWorkerCompletedEventArgs"/> instance containing the event data.</param>
        protected override void OnLoadBackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            base.OnLoadBackgroundWorkerRunWorkerCompleted(sender, e);

            if (null == e.Error)
            {
                base.DataSource = e.Result;

                for (int rowIndex = 0; rowIndex < this.dataGridView.SelectedRows.Count; rowIndex++)
                    this.dataGridView.SelectedRows[rowIndex].Selected = false;

                base.Cursor = Cursors.Default;
            }
            else if (e.Error is CommunicationException)
            {
                MessageBoxService.ReportError(this, Properties.Resources.GlobalConnectionFailed);
            }
            else
            {
                if (!ExceptionPolicy.HandleException(e.Error, Constants.SmartClientExceptionPolicy))
                    throw e.Error;
            }
        }

        /// <summary>
        /// Handles the RunWorkerCompleted event of the acceptActionBackgroundWorker control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.RunWorkerCompletedEventArgs"/> instance containing the event data.</param>
        protected override void OnAcceptActionBackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            base.OnAcceptActionBackgroundWorkerRunWorkerCompleted(sender, e);

            this.StartSession();
        }

        /// <summary>
        /// Handles the LinkClicked event of the newSessionLinkLabel control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void newSessionLinkLabel_LinkClicked(object sender, EventArgs e)
        {
            MainForm mainForm = (this.Owner as MainForm);
            if (null != mainForm)
            {
                mainForm.ProcessModalDialog<EditSessionForm>();

                base.Cursor = Cursors.WaitCursor;
                base.LoadBackgroundWorker.RunWorkerAsync();
            }
        }

        /// <summary>
        /// Handles the CellPainting event of the dataGridView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.DataGridViewCellPaintingEventArgs"/> instance containing the event data.</param>
        private void dataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (0 == e.ColumnIndex)
            {
                e.PaintBackground(e.CellBounds, true);

                if (-1 == e.RowIndex)
                {
                    // Draw header image
                    DataGridViewUtils.DrawBitmapInCell(Properties.Resources.RequiresPasswordHeaderIcon, e);
                }
                else
                {
                    Session session = (this.bindingSource[e.RowIndex] as Session);
                    if ((null != session) && session.RequiresPassword)
                        DataGridViewUtils.DrawBitmapInCell(Properties.Resources.RequiresPasswordIcon, e);
                }

                e.Handled = true;
            }
            else if (1 == e.ColumnIndex)
            {
                e.PaintBackground(e.CellBounds, true);

                if (-1 == e.RowIndex)
                {
                    // Draw header image
                    DataGridViewUtils.DrawBitmapInCell(Properties.Resources.RecurrentHeaderIcon, e);
                }
                else
                {
                    Session session = (this.bindingSource[e.RowIndex] as Session);
                    if ((null != session) && session.Recurrent)
                        DataGridViewUtils.DrawBitmapInCell(Properties.Resources.RecurrentIcon, e);
                }

                e.Handled = true;
            }
        }

        /// <summary>
        /// Handles the SelectionChanged event of the dataGridView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void dataGridView_SelectionChanged(object sender, EventArgs e)
        {
            base.AcceptButton.Enabled = (0 < this.dataGridView.SelectedRows.Count);
        }

        /// <summary>
        /// Handles the Opening event of the contextMenuStrip control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
        private void contextMenuStrip_Opening(object sender, CancelEventArgs e)
        {
            e.Cancel = (0 >= this.dataGridView.SelectedRows.Count);
        }

        /// <summary>
        /// Handles the Click event of the startThisSessionToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void startThisSessionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.StartSession();
        }

        /// <summary>
        /// Handles the Click event of the editSessionToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void editSessionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Session session = (this.bindingSource.Current as Session);
            if (null != session)
            {
                using (EditSessionForm editSessionForm = new EditSessionForm())
                {
                    editSessionForm.DataSource = session;

                    if (DialogResult.OK == editSessionForm.ShowDialog(this))
                    {
                        base.Cursor = Cursors.WaitCursor;
                        session = (Session) editSessionForm.DataSource;

                        this.editBackgroundWorker.RunWorkerAsync(session);
                    }
                }
            }
        }

        /// <summary>
        /// Handles the DoWork event of the editBackgroundWorker control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.DoWorkEventArgs"/> instance containing the event data.</param>
        private void editBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            Session session = (Session) e.Argument;

            using (SchedulerServiceProxy sessionManager = new SchedulerServiceProxy())
            {
                sessionManager.UpdateSession(session);
            }
        }

        /// <summary>
        /// Handles the RunWorkerCompleted event of the editBackgroundWorker control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.RunWorkerCompletedEventArgs"/> instance containing the event data.</param>
        private void editBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (null == e.Error)
            {
                base.LoadBackgroundWorker.RunWorkerAsync();
            }
            else if (e.Error is CommunicationException)
            {
                MessageBoxService.ReportError(this, Properties.Resources.GlobalConnectionFailed);
            }
            else
            {
                if (!ExceptionPolicy.HandleException(e.Error, Constants.SmartClientExceptionPolicy))
                    throw e.Error;
            }
        }

        /// <summary>
        /// Handles the Click event of the deleteSessionToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void deleteSessionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Session session = (this.bindingSource.Current as Session);
            if ((null != session) && (DialogResult.Yes == MessageBoxService.ReportQuestion(this, MessageBoxButtons.YesNoCancel, MessageBoxDefaultButton.Button2,
                Properties.Resources.StartSessionFormConfirmDelete)))
            {
                base.Cursor = Cursors.WaitCursor;
                this.deleteBackgroundWorker.RunWorkerAsync(session.SessionId);
            }
        }

        /// <summary>
        /// Handles the DoWork event of the deleteBackgroundWorker control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.DoWorkEventArgs"/> instance containing the event data.</param>
        private void deleteBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            int sessionId = (int) e.Argument;

            using (SchedulerServiceProxy sessionManager = new SchedulerServiceProxy())
            {
                sessionManager.DeleteSession(sessionId);
            }
        }

        /// <summary>
        /// Handles the RunWorkerCompleted event of the deleteBackgroundWorker control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.RunWorkerCompletedEventArgs"/> instance containing the event data.</param>
        private void deleteBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (null == e.Error)
            {
                base.LoadBackgroundWorker.RunWorkerAsync();
                MessageBoxService.ReportInfo(this, Properties.Resources.StartSessionFormDeleteSucceded);
            }
            else if (e.Error is CommunicationException)
            {
                MessageBoxService.ReportError(this, Properties.Resources.GlobalConnectionFailed);
            }
            else
            {
                if (!ExceptionPolicy.HandleException(e.Error, Constants.SmartClientExceptionPolicy))
                    throw e.Error;
            }
        }

        private void dataGridView_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (-1 < e.RowIndex)
                this.StartSession();
        }

        private void StartSession()
        {
            Session session = (base.bindingSource.Current as Session);
            if (null != session)
            {
                foreach (Form form in Application.OpenForms)
                {
                    if (form is MainForm)
                    {
                        form.Hide();
                        break;
                    }
                }

                BrokerProgressForm.StartSession(this, session);
            }
        }
    }
}